package org.unidata.mdm.meta.type.model.attributes;

import static org.unidata.mdm.meta.type.model.ModelNamespace.META_MODEL_NAMESPACE;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.unidata.mdm.meta.type.model.ArrayValueType;
import org.unidata.mdm.meta.type.model.OrderedElement;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.google.common.base.MoreObjects;


@JsonPropertyOrder({
    "lookupEntityDisplayAttributes",
    "lookupEntitySearchAttributes",
    "dictionaryDataType"})
public class ArrayMetaModelAttribute
    extends AbstractSearchableMetaModelAttribute<ArrayMetaModelAttribute>
    implements OrderedElement, SearchableMetaModelAttribute {
    /**
     * GSVUID.
     */
    private static final long serialVersionUID = 2644427651751424857L;

    private static final String DEFAULT_EXCHANGE_SEPARATOR = "|";

    @JacksonXmlProperty(namespace = META_MODEL_NAMESPACE)
    private List<String> lookupEntityDisplayAttributes;

    @JacksonXmlProperty(namespace = META_MODEL_NAMESPACE)
    private List<String> lookupEntitySearchAttributes;

    @JacksonXmlProperty(namespace = META_MODEL_NAMESPACE)
    private List<String> dictionaryDataType;

    @JacksonXmlProperty(isAttribute = true)
    private boolean useAttributeNameForDisplay;

    @JacksonXmlProperty(isAttribute = true)
    private ArrayValueType arrayValueType;

    @JacksonXmlProperty(isAttribute = true)
    private boolean nullable;

    @JacksonXmlProperty(isAttribute = true)
    private boolean searchMorphologically;

    @JacksonXmlProperty(isAttribute = true)
    private boolean searchCaseInsensitive;

    @JacksonXmlProperty(isAttribute = true)
    private String lookupEntityType;

    @JacksonXmlProperty(isAttribute = true)
    private ArrayValueType lookupEntityCodeAttributeType;

    @JacksonXmlProperty(isAttribute = true)
    private String exchangeSeparator;

    @JacksonXmlProperty(isAttribute = true)
    private int order;

    // WITH
    
    public List<String> getLookupEntityDisplayAttributes() {
        if (lookupEntityDisplayAttributes == null) {
            lookupEntityDisplayAttributes = new ArrayList<>();
        }
        return this.lookupEntityDisplayAttributes;
    }

    public List<String> getLookupEntitySearchAttributes() {
        if (lookupEntitySearchAttributes == null) {
            lookupEntitySearchAttributes = new ArrayList<>();
        }
        return this.lookupEntitySearchAttributes;
    }

    public List<String> getDictionaryDataType() {
        if (dictionaryDataType == null) {
            dictionaryDataType = new ArrayList<>();
        }
        return this.dictionaryDataType;
    }

    public void setLookupEntityDisplayAttributes(List<String> lookupEntityDisplayAttributes) {
        this.lookupEntityDisplayAttributes = lookupEntityDisplayAttributes;
    }

    public void setLookupEntitySearchAttributes(List<String> lookupEntitySearchAttributes) {
        this.lookupEntitySearchAttributes = lookupEntitySearchAttributes;
    }

    public void setDictionaryDataType(List<String> dictionaryDataType) {
        this.dictionaryDataType = dictionaryDataType;
    }

    public boolean isUseAttributeNameForDisplay() {
        return useAttributeNameForDisplay;
    }

    public void setUseAttributeNameForDisplay(boolean useAttributeNameForDisplay) {
        this.useAttributeNameForDisplay = useAttributeNameForDisplay;
    }

    public ArrayValueType getArrayValueType() {
        return arrayValueType;
    }

    public void setArrayValueType(ArrayValueType arrayValueType) {
        this.arrayValueType = arrayValueType;
    }

    public boolean isNullable() {
        return nullable;
    }

    public void setNullable(boolean nullable) {
        this.nullable = nullable;
    }

    public boolean isSearchMorphologically() {
        return searchMorphologically;
    }

    public void setSearchMorphologically(boolean searchMorphologically) {
        this.searchMorphologically = searchMorphologically;
    }

    public boolean isSearchCaseInsensitive() {
        return searchCaseInsensitive;
    }

    public void setSearchCaseInsensitive(boolean searchCaseInsensitive) {
        this.searchCaseInsensitive = searchCaseInsensitive;
    }

    public String getLookupEntityType() {
        return lookupEntityType;
    }

    public void setLookupEntityType(String lookupEntityType) {
        this.lookupEntityType = lookupEntityType;
    }

    public ArrayValueType getLookupEntityCodeAttributeType() {
        return lookupEntityCodeAttributeType;
    }

    public void setLookupEntityCodeAttributeType(ArrayValueType lookupEntityCodeAttributeType) {
        this.lookupEntityCodeAttributeType = lookupEntityCodeAttributeType;
    }

    public String getExchangeSeparator() {
        return MoreObjects.firstNonNull(exchangeSeparator, DEFAULT_EXCHANGE_SEPARATOR);
    }

    public void setExchangeSeparator(String exchangeSeparator) {
        this.exchangeSeparator = exchangeSeparator;
    }

    @Override
    public int getOrder() {
        return order;
    }

    @Override
    public void setOrder(int order) {
        this.order = order;
    }

    // WITH
    public ArrayMetaModelAttribute withLookupEntityDisplayAttributes(String... lookupEntityDisplayAttributes) {
        if (lookupEntityDisplayAttributes != null) {
            Collections.addAll(getLookupEntityDisplayAttributes(), lookupEntityDisplayAttributes);
        }
        return this;
    }

    public ArrayMetaModelAttribute withLookupEntityDisplayAttributes(Collection<String> lookupEntityDisplayAttributes) {
        if (lookupEntityDisplayAttributes != null && !lookupEntityDisplayAttributes.isEmpty()) {
            getLookupEntityDisplayAttributes().addAll(lookupEntityDisplayAttributes);
        }
        return this;
    }


    public ArrayMetaModelAttribute withLookupEntitySearchAttributes(String... lookupEntitySearchAttributes) {
        if (lookupEntitySearchAttributes != null) {
            Collections.addAll(getLookupEntitySearchAttributes(), lookupEntitySearchAttributes);
        }
        return this;
    }

    public ArrayMetaModelAttribute withLookupEntitySearchAttributes(Collection<String> lookupEntitySearchAttributes) {
        if (lookupEntitySearchAttributes != null && !lookupEntitySearchAttributes.isEmpty()) {
            getLookupEntitySearchAttributes().addAll(lookupEntitySearchAttributes);
        }
        return this;
    }

    public ArrayMetaModelAttribute withDictionaryDataType(String... dictionaryDataType) {
        if (dictionaryDataType != null) {
            Collections.addAll(getDictionaryDataType(), dictionaryDataType);
        }
        return this;
    }

    public ArrayMetaModelAttribute withDictionaryDataType(Collection<String> dictionaryDataType) {
        if (dictionaryDataType != null && !dictionaryDataType.isEmpty()) {
            getDictionaryDataType().addAll(dictionaryDataType);
        }
        return this;
    }

    // WITH

}
